/*
 * Copyright (c) 2025 CAX Conversion Project
 */
package com.comac.ins.bomt.service.impl;

import com.comac.ins.bomt.common.enums.BizFileTypeEnum;
import com.comac.ins.bomt.common.enums.BizStepEnum;
import com.comac.ins.bomt.common.enums.BomInfoStatusEnum;
import com.comac.ins.bomt.domain.*;
import com.comac.ins.bomt.domain.response.OriginalBomUploadResponse;
import com.comac.ins.bomt.domain.vo.*;
import com.comac.ins.bomt.repository.BomRepository;
import com.comac.ins.bomt.service.*;
import com.comac.ins.bomt.utils.BomVersionUtil;
import com.comac.ins.common.core.domain.model.LoginUser;
import com.comac.ins.common.core.utils.BizAssertUtil;
import com.comac.ins.common.json.utils.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Bom管理服务实现
 *
 * @author zhanghongyi
 * @date 2024 /8/6 16:30
 * @description BomManageServiceImpl
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class BomManageServiceImpl implements BomManageService {

    private final BomRepository bomRepository;

    private final BomQueryService bomQueryService;

    private final KeywordListService keywordListService;

    private final BizFileService fileService;

    private final SectionService sectionService;

    private final BomFileParseService bomFileParseService;

    private final BomGenerateService bomGenerateService;

    private final BomCoreService bomCoreService;

    @Override
    public OriginalBomUploadResponse uploadOrigin(LoginUser loginUser, MultipartFile file, String aircraftModel, String desc) {
        //批次号生成，暂时采用时间戳，调用量大了可考虑使用数据库序列
        String track = MessageFormat.format("{0}_{1}", aircraftModel, DateFormatUtils.format(new Date(), "yyyy_MM_dd_HHmmssSSSSSS"));
        //获取分组
        Map<String, String> reverseGroupConfig = sectionService.getReverseSectionGroupConfig(aircraftModel);
        //获取需删除关键词
        List<String> deleteWords = keywordListService.queryByBindType(loginUser, BizStepEnum.OBOM_SBOM_CONVERT, aircraftModel);
        log.info("upload origin:{}, track:{},deleteWords:{}", file.getOriginalFilename(), track, JsonUtils.toJsonString(deleteWords));
        //解析
        List<DetailOriginalBomVo> originalBomVos = bomFileParseService.parseOrigin(file);
        log.info("track:{},origin record size:{}", track, originalBomVos.size());
        //转化
        List<String> noticeMessages = new ArrayList<>();
        Map<String, List<DetailStandardBomVo>> groupedStandardVos = bomCoreService.convertOriginToStandard(loginUser, originalBomVos, reverseGroupConfig, deleteWords, aircraftModel, track, noticeMessages);
        FileExtraInfo extra = new FileExtraInfo();
        extra.setDeleteWords(deleteWords);
        extra.setReverseGroupConfig(reverseGroupConfig);
        extra.setBatchDesc(desc);
        BizFileVo fileVo = doUploadOrigin(loginUser, file, aircraftModel, track, extra);

        List<BomInfoVo> bomInfoList = bomGenerateService.beginGenerateStandard(loginUser, groupedStandardVos, aircraftModel, track, fileVo);
        return buildUploadOriginResponse(track, fileVo, bomInfoList, noticeMessages);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadInit(LoginUser loginUser, MultipartFile file, String aircraftModel, String desc) {
        String track = MessageFormat.format("{0}_{1}", aircraftModel, DateFormatUtils.format(new Date(), "yyyy_MM_dd_HHmmssSSSSSS"));
        Map<String, List<DetailStandardBomVo>> groupedStandard = bomFileParseService.parseStandard(loginUser, file, aircraftModel, track);
        Map<String, List<DetailStrengthBom>> groupedStrength = bomFileParseService.parseStrength(loginUser, file, aircraftModel, track);
        FileExtraInfo extra = new FileExtraInfo();
        extra.setBatchDesc(desc);
        BizFileVo fileVo = doUploadInit(loginUser, file, aircraftModel, track, extra);
        List<BomInfo> bomInfoList = bomRepository.initBomRecords(loginUser, groupedStandard.keySet().stream().toList(), aircraftModel, track, fileVo);
        //发送标准装机清单生成消息
        for (BomInfo bomInfo : bomInfoList) {
            //初始化标准装机清单明细
            bomRepository.initStandardBomDetail(loginUser, aircraftModel, track, bomInfo.getGroupType(), groupedStandard.get(bomInfo.getGroupType()));
            //初始化强度数模清单明细
            bomRepository.initStrengthBomDetail(loginUser, aircraftModel, track, bomInfo.getGroupType(), groupedStrength.get(bomInfo.getGroupType()));
            //更新Bom状态
            bomInfo.setStandardBomSummary(JsonUtils.toJsonString(new SummaryStandardBomVo(BomVersionUtil.getVersions(groupedStandard.get(bomInfo.getGroupType())))));
            bomInfo.setStandardBomFileId(fileVo.getFileId());
            bomInfo.setStrengthBomSummary(JsonUtils.toJsonString(new SummaryStrengthBomVo(BomVersionUtil.getVersions(groupedStrength.get(bomInfo.getGroupType())))));
            bomInfo.setStrengthBomFileId(fileVo.getFileId());
            bomInfo.setStatus(BomInfoStatusEnum.DONE.getCode());
            bomRepository.updateBomInfo(bomInfo);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyStandardBomDetail(LoginUser loginUser, List<DetailStandardBomVo> modifyDetails, List<Long> deleteIds) {
        if (CollectionUtils.isNotEmpty(deleteIds)) {
            bomRepository.deleteStandardBomDetails(deleteIds);
        }
        if (CollectionUtils.isNotEmpty(modifyDetails)) {
            bomRepository.modifyStandardBomDetails(modifyDetails);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyStrengthBomDetail(LoginUser loginUser, List<DetailStrengthBomVo> modifyDetails, List<Long> deleteIds) {
        if (CollectionUtils.isNotEmpty(deleteIds)) {
            bomRepository.deleteStrengthBomDetails(deleteIds);
        }
        if (CollectionUtils.isNotEmpty(modifyDetails)) {
            bomRepository.modifyStrengthBomDetails(modifyDetails);
        }
    }


    @Override
    public void uploadModelStatus(LoginUser loginUser, MultipartFile file, String aircraftModel, String track) {
        List<BomInfo> bomInfos = bomQueryService.getBomInfoListByModelTrack(aircraftModel, track);
        bomInfos.forEach(bomInfo -> BizAssertUtil.isFalse(StringUtils.equals(bomInfo.getStatus(), BomInfoStatusEnum.DOING.getCode()), "exist bom is processing,please wait"));
        Map<String, List<DetailModelStatus>> groupedModel = bomFileParseService.parseModelStatus(loginUser, file, aircraftModel, track);
        for (Map.Entry<String, List<DetailModelStatus>> groupEntry : groupedModel.entrySet()) {
            bomRepository.initModelStatusDetail(loginUser, aircraftModel, track, groupEntry.getKey(), groupEntry.getValue());
        }
        BizFileVo fileVo = doUploadModelStatusZip(loginUser, file, aircraftModel, track, null);
        //查找并修改Bom记录
        Map<String, List<BomInfo>> groupedBomMap = bomInfos.stream().collect(Collectors.groupingBy(BomInfo::getGroupType));
        for (Map.Entry<String, List<DetailModelStatus>> groupEntry : groupedModel.entrySet()) {
            BomInfo bomInfo = groupedBomMap.containsKey(groupEntry.getKey()) ? groupedBomMap.get(groupEntry.getKey()).get(0) : null;
            if (null != bomInfo) {
                bomInfo.setModelStatusBomFileId(fileVo.getFileId());
                bomRepository.updateBomInfo(bomInfo);
            }
        }
    }


    private BizFileVo doUploadInit(LoginUser loginUser, MultipartFile file, String aircraftModel, String track, FileExtraInfo extra) {
        return fileService.upload(loginUser, BizFileTypeEnum.INIT, file, track, aircraftModel, "", extra);
    }

    private BizFileVo doUploadOrigin(LoginUser loginUser, MultipartFile file, String aircraftModel, String track, FileExtraInfo extra) {
        return fileService.upload(loginUser, BizFileTypeEnum.OBOM, file, track, aircraftModel, "", extra);
    }

    private BizFileVo doUploadModelStatusZip(LoginUser loginUser, MultipartFile file, String aircraftModel, String track, FileExtraInfo extra) {
        return fileService.upload(loginUser, BizFileTypeEnum.MSTS, file, track, aircraftModel, "", extra);
    }


    private OriginalBomUploadResponse buildUploadOriginResponse(String track, BizFileVo fileVo, List<BomInfoVo> bomInfoList, List<String> noticeMessage) {
        OriginalBomUploadResponse response = new OriginalBomUploadResponse();
        response.setOriginalBomFile(fileVo);
        response.setBomInfoList(bomInfoList);
        response.setTrack(track);
        response.setNoticeMessages(noticeMessage);
        return response;
    }
}

